package com.dongzili.query.common.config.openapi;

import com.fasterxml.jackson.databind.type.SimpleType;
import io.swagger.v3.core.converter.AnnotatedType;
import io.swagger.v3.core.converter.ModelConverter;
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.oas.models.media.Schema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
public class CustomEnumModelConverter implements ModelConverter {

    private static final Logger logger = LoggerFactory.getLogger(CustomEnumModelConverter.class);

    @Override
    public Schema<?> resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
        Type javaType = type.getType();
        if(javaType instanceof SimpleType ){
            SimpleType simpleType = ((SimpleType)javaType);
            if(simpleType.getSuperClass() != null && simpleType.getSuperClass().isEnumType()){
                // 处理枚举类型
                Class<?> enumClass = simpleType.getRawClass();
                Schema<Object> schema = new Schema<>();
                schema.setType("string");
                Map<String, Map<String, Object>>maps = getEnumValues(enumClass);
                for (Map.Entry<String, Map<String, Object>> entry : maps.entrySet()) {
                    schema.addEnumItemObject(entry.getKey() + "(" + entry.getValue() + ")");
                }
                return schema;
            }
        }
        // 其他类型交给下一个转换器处理
        return chain.hasNext() ? chain.next().resolve(type, context, chain) : null;
    }

    public static Map<String, Map<String, Object>> getEnumValues(Class<?> enumClass) {
        Map<String, Map<String, Object>> enumValueMap = new HashMap<>();
        if (enumClass.isEnum()) {
            Object[] enumConstants = enumClass.getEnumConstants();
            Field[] fields = enumClass.getDeclaredFields();
            for (Object enumConstant : enumConstants) {
                String enumName = enumConstant.toString();
                Map<String, Object> fieldValueMap = new HashMap<>();
                for (Field field : fields) {
                    if (!field.isEnumConstant() && !field.getName().equals("$VALUES")) {
                        try {
                            field.setAccessible(true);
                            Object fieldValue = field.get(enumConstant);
                            fieldValueMap.put(field.getName(), fieldValue);
                        } catch (IllegalAccessException e) {
                            logger.error(e.getMessage());
                        }
                    }
                }
                enumValueMap.put(enumName, fieldValueMap);
            }
        }
        return enumValueMap;
    }
}